class_name SimpleCamera
extends Camera2D

# cam follow
@export var follow_target:Node2D
var is_following: bool = true
@export var follow_offset_2_target: Vector2 = Vector2.UP * 18
@export var speed_factor:float = 0.5

# cam limit
@export var cam_limit:Node2D

# mouse dir offset
var follow_mouse_dir_offset: Vector2
@export var follow_mouse_dir_offset_strength: float = 0.2
@export var follow_mouse_dir_offset_max_length: float = 50

# level
var level: Level

# cam shake
var shake_intensity: float = 0.0
var shake_timer: float = 0.0
var shake_offset: Vector2 = Vector2.ZERO
@export var shake_frequency: float = 30.0 # 抖动频率，数值越大抖动越快


func _ready() -> void:
	set_cam_limit()
	
	await get_tree().process_frame
	follow_immediate()
		

func follow_immediate():
	if follow_target:
		global_position = get_follow_position()
		

func get_follow_position():
	var follow_target_pos = follow_target.global_position + follow_offset_2_target
	
	var mouse_world_pos = level.screen_2_world_pos(get_viewport().get_mouse_position())
	var offset = mouse_world_pos - follow_target_pos
	offset *= follow_mouse_dir_offset_strength
	offset = offset.limit_length(follow_mouse_dir_offset_max_length)
	
	return follow_target_pos + offset
		
	
func set_cam_limit():
	if not cam_limit or cam_limit.get_child_count() <= 0: return
	
	var left = cam_limit.find_child("Left") as Marker2D
	var top = cam_limit.find_child("Top") as Marker2D
	var right = cam_limit.find_child("Right") as Marker2D
	var bottom = cam_limit.find_child("Bottom") as Marker2D
	
	limit_left = left.global_position.x
	limit_top = top.global_position.y
	limit_right = right.global_position.x
	limit_bottom = bottom.global_position.y


func _physics_process(delta: float) -> void:
	if not follow_target: return
	if not is_following: return
	
	global_position = lerp(global_position, get_follow_position(), speed_factor)
	
	# 更新震动
	if shake_timer > 0:
		shake_timer -= delta
		# 产生随机偏移 (sin+cos 比纯随机更顺滑)
		shake_offset = Vector2(
			sin(Time.get_ticks_msec() / 1000.0 * shake_frequency),
			cos(Time.get_ticks_msec() / 1000.0 * shake_frequency)
		) * shake_intensity
		
		# 震动强度逐渐衰减
		shake_intensity = lerp(shake_intensity, 0.0, delta * 5.0)
	else:
		shake_offset = Vector2.ZERO
	
	# 应用震动
	global_position += shake_offset


# 外部调用来触发震动
func start_shake(intensity: float = 10.0, duration: float = 0.3):
	shake_intensity = intensity
	shake_timer = duration
